package cn.wl.hrm.service.impl;

import cn.wl.hrm.domain.Sso;
import cn.wl.hrm.domain.VerifyCode;
import cn.wl.hrm.domain.VipBase;
import cn.wl.hrm.dto.RegisterDto;
import cn.wl.hrm.feign.client.RedisFeignClient;
import cn.wl.hrm.mapper.SsoMapper;
import cn.wl.hrm.mapper.VipBaseMapper;
import cn.wl.hrm.service.ISsoService;
import cn.wl.hrm.util.AjaxResult;
import cn.wl.hrm.util.encrypt.MD5;
import cn.wl.hrm.vo.SendSmsCodeVo;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.UUID;

/**
 * <p>
 * 会员登录账号 服务实现类
 * </p>
 *
 * @author wl
 * @since 2020-04-29
 */
@Service
public class SsoServiceImpl extends ServiceImpl<SsoMapper, Sso> implements ISsoService {
    @Autowired
    private RedisFeignClient redisFeignClient;

    @Autowired
    private VipBaseMapper vipBaseMapper;

    @Override
    public void register(RegisterDto registerDto) {
        //获取前端传来的参数
        String mobile = registerDto.getMobile();
        String password = registerDto.getPassword();
        String smsCode = registerDto.getSmsCode();
        //判断参数是否有效
        if(StringUtils.isBlank(mobile)){
            throw new RuntimeException("无效的手机号");
        }
        if(StringUtils.isBlank(password)){
            throw new RuntimeException("无效的密码");
        }
        if(StringUtils.isBlank(smsCode)){
            throw new RuntimeException("无效的短信验证码");
        }
        Sso ssoByMysql = baseMapper.selectByPhone(mobile);
        if(ssoByMysql != null){
            throw new RuntimeException("您注册的手机号已被使用，请更换手机号进行注册！");
        }
        //从redis获取短信验证码
        AjaxResult ajaxResult = redisFeignClient.get(VerifyCode.SMS_CODE_KEY + mobile);
        if(!ajaxResult.isSuccess() || ajaxResult.getResultObj() == null){
            throw new RuntimeException("验证码已过期，请重新发送！");
        }
        //获取到redis中短信验证码的值，将其转换为sendSmsCodeVo对象
        String sendSmsCodeVoJson = ajaxResult.getResultObj().toString();
        SendSmsCodeVo sendSmsCodeVo = JSON.parseObject(sendSmsCodeVoJson, SendSmsCodeVo.class);
        //判断验证码是否一样
        if(!sendSmsCodeVo.getSmsCodeValue().toUpperCase().equals(smsCode.toUpperCase())){
            throw new RuntimeException("短信验证码错误，请重新输入！");
        }
        //创建用户信息对象
        Sso sso = new Sso();
        //设置手机号码
        sso.setPhone(mobile);
        //设置盐值
        String salt = MD5.getRandomCode(16);
        //加密加盐
        String md5Password = MD5.getMD5(password + salt);
        //保存盐值
        sso.setSalt(salt);
        //保存加密之后的密码
        sso.setPassword(md5Password);
        //设置创建时间
        long nowTime = new Date().getTime();


        sso.setCreateTime(nowTime);
        baseMapper.insert(sso);

        //创建用户基本信息对象
        VipBase vipBase = new VipBase();
        //设置用户id
        vipBase.setSsoId(sso.getId());
        //设置注册渠道
        vipBase.setRegChannel(1);
        //设置创建时间
        vipBase.setCreateTime(nowTime);
        //设置注册时间
        vipBase.setRegTime(nowTime);
        //添加到vipBase对应的表中
        vipBaseMapper.insert(vipBase);
    }

    @Override
    public String login(Sso sso) {
        //判断参数
        if(StringUtils.isBlank(sso.getPhone()) || StringUtils.isBlank(sso.getPassword())){
            throw new RuntimeException("用户名或密码不能为空");
        }
        //根据用户名查询数据库中的用户
        Sso ssoFromMysql = baseMapper.selectByPhone(sso.getPhone());
        //数据库中密码是加密过的，所以需要将前端传过来的密码加密，然后比较
        String password = sso.getPassword();
        String salt = ssoFromMysql.getSalt();
        String md5Pass = MD5.getMD5(password + salt);
        //判断密码是否正确
        if(!ssoFromMysql.getPassword().equals(md5Pass)){
            throw new RuntimeException("密码错误");
        }
        //生成redis的key
        String token = UUID.randomUUID().toString().replaceAll("-", "");
        //将登录信息放进redis
        AjaxResult result = redisFeignClient.setex(token, 24 * 60 * 60, JSON.toJSONString(ssoFromMysql));
        if(!result.isSuccess()){
            throw new RuntimeException("登录信息放进redis失败！");
        }
        //返回redis的key给客户端
        return token;
    }
}
